import Food from './Food'

import ScorePanel from './ScorePanel';

import Snake from './Snake';

class GameControl {
    food: Food;
    snake: Snake;
    scorePanel: ScorePanel;
    // 移动方向
    direction: string = '';
    // 是否存活
    isLive: boolean = true;
    // 定时器
    timer: number = 0;

    constructor() {
        this.food = new Food()
        this.snake = new Snake()
        this.scorePanel = new ScorePanel()
        this.init();
    }

    // 初始化
    init() {
        // 添加键盘按下相应事件
        document.addEventListener('keydown', this.keydownHandler.bind(this))
    }

    // 键盘按下事件，更改移动方向
    keydownHandler(event: KeyboardEvent) {
        const dir = event.key;
        // 判断不可是上次的反方向，用于限制不可反方向移动
        if (this.getOppositeDirection(dir) !== this.direction) {
            this.direction = dir;
        }
        this.isLive && this.run();
    }

    // 获取反方向
    getOppositeDirection(direction: string) {
        switch (direction) {
            case "ArrowUp":
                return "ArrowDown"
            case "ArrowDown":
                return "ArrowUp"
            case "ArrowLeft":
                return "ArrowRight"
            case "ArrowRight":
                return "ArrowLeft"
        }
    }

    // 根据移动反向移动
    run() {
        let X = this.snake.X;
        let Y = this.snake.Y;
        switch (this.direction) {
            case "ArrowUp":
                Y -= 10;
                break;
            case "ArrowDown":
                Y += 10;
                break;
            case "ArrowLeft":
                X -= 10;
                break;
            case "ArrowRight":
                X += 10;
                break;
        }
        // 吃到食物的逻辑
        this.checkEat()
        // 移动
        try {
            this.snake.moveBody();
            this.snake.X = X;
            this.snake.Y = Y;
            this.snake.checkSelf();
        } catch (e) {
            alert((e as Error).message)
            this.isLive = false;
        }
        // 每次移动完，过一段时间继续继续调用移动函数，做到持续移动的效果
        if (this.isLive) {
            clearTimeout(this.timer);
            this.timer = window.setTimeout(this.run.bind(this), 300 - (this.scorePanel.level-1)*30);
        }
    }

    // 检查蛇是否吃到食物
    checkEat() {
        if (this.snake.X === this.food.X && this.snake.Y === this.food.Y) {
            this.food.change()
            this.scorePanel.addScore()
            this.snake.addBody()
        }
    }
}

export default GameControl;